package com.example.browser;

import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import java.util.ArrayList;
import java.util.List;

public class MyWebView extends WebView {

    private static final String CUSTOM_MENU_JS_INTERFACE = "CustomMenuJSInterface";
    private ActionMode mActionMode;
    private ActionSelectListener mActionSelectListener;
    private List<String> mCustomMenuList = new ArrayList<>(); //自定义添加的选项
    private OnScrollChangeListener mOnScrollChangeListener;
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        // webview的高度
        float webcontent = getContentHeight() * getScale();
        // 当前webview的高度
        float webnow = getHeight() + getScrollY();
        if (Math.abs(webcontent - webnow) < 1) {
            //处于底端
            mOnScrollChangeListener.onPageEnd(l, t, oldl, oldt);
        } else if (getScrollY() == 0) {
            //处于顶端
            mOnScrollChangeListener.onPageTop(l, t, oldl, oldt);
        } else {
            mOnScrollChangeListener.onScrollChanged(l, t, oldl, oldt);
        }
    }

    public void setOnScrollChangeListener(OnScrollChangeListener listener) {
        this.mOnScrollChangeListener = listener;
    }

    public interface OnScrollChangeListener {

        public void onPageEnd(int l, int t, int oldl, int oldt);

        public void onPageTop(int l, int t, int oldl, int oldt);

        public void onScrollChanged(int l, int t, int oldl, int oldt);

    }
    public interface ActionSelectListener {
        void onClick(String value, String title);
    }

    /**
     * 设置点击回掉
     *
     * @param actionSelectListener
     */
    public void setActionSelectListener(ActionSelectListener actionSelectListener) {
        this.mActionSelectListener = actionSelectListener;
    }

    /**
     * 自定义菜单 start
     */
    @SuppressLint("JavascriptInterface")
    private void initMenu() {
        addJavascriptInterface(new ActionSelectInterface(getContext()), CUSTOM_MENU_JS_INTERFACE);
    }

    /**
     * js选中的回掉接口
     */
    private class ActionSelectInterface {

        Context mContext;

        ActionSelectInterface(Context context) {
            mContext = context;
        }

        @JavascriptInterface
        public void callback(final String value, final String title) {
            if (mActionSelectListener != null) {
                mActionSelectListener.onClick(title, value);
            }
        }
    }

    public MyWebView(@NonNull Context context) {
        super(context);
        initMenu();
    }

    public MyWebView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public MyWebView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public MyWebView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public ActionMode startActionMode(ActionMode.Callback callback) {
        return super.startActionMode(buildCustomCallback(callback));
//        return super.startActionMode(callback);
    }

    @Override
    public ActionMode startActionMode(ActionMode.Callback callback, int type) {
        return super.startActionMode(buildCustomCallback(callback), type);
//        return super.startActionMode(callback, type);
    }


    public void setMenuText(String search,String add) {
        mCustomMenuList.clear();
        if (!TextUtils.isEmpty(search)) {
            mCustomMenuList.add(search);
        }

        if (!TextUtils.isEmpty(add)) {
            mCustomMenuList.add(add);
        }
    }

    /**
     * 自定义callback，用于菜单过滤
     *
     * @param callback
     * @return
     */
    private ActionMode.Callback buildCustomCallback(final ActionMode.Callback callback) {
        ActionMode.Callback customCallback;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            customCallback = new ActionMode.Callback2() {
                @Override
                public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                    Log.d("chenyu", "buildCustomCallback onCreateActionMode: start ...........");
                    return callback.onCreateActionMode(mode, menu);
                }

                @Override
                public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                    Log.d("chenyu", "buildCustomCallback onPrepareActionMode: start ...........");
                    callback.onPrepareActionMode(mode, menu);
                    addCustomMenu(mode);
                    Log.d("chenyu", "addCustomMenu after : menu size is:" + menu.size());
                    for (int i = 0; i < menu.size(); i++) {
                        MenuItem menuItem = menu.getItem(i);
                        Log.d("chenyu", "addCustomMenu after : menuItem getItem(" + i + ")" + menu.getItem(i));
                        Log.d("chenyu", "addCustomMenu after : menuItem getItem(" + i + ") itemId is" + menu.getItem(i).getItemId());
                    }

                    for (int i = 0; i < menu.size(); i++) {
                        MenuItem menuItem = menu.getItem(i);
//                        if (!isMenuStay(menuItem)) {
//                        menuItem.setVisible(false);
                        if (i == 5) {
                            menuItem.setVisible(false);
                        } else {
                            if (menuItem.getItemId() == 0) {
                                //自定义或是通过PROCESS_TEXT方案加入到菜单中的选项，item都为0
                                Intent intent = menuItem.getIntent();
                                ComponentName componentName = intent == null ? null : intent.getComponent();
                                //根据包名比较菜单中的选项是否是本app加入的
                                if (componentName != null && getContext().getPackageName().equals(componentName.getPackageName())) {
                                    menuItem.setVisible(true);
                                } else {
                                    menuItem.setVisible(false);
                                }
                            } else {
                                menuItem.setVisible(true);
                            }
                        }
                    }
                    return true;
                }

                @Override
                public boolean onActionItemClicked(ActionMode mode, MenuItem item) {

                    if (item == null || TextUtils.isEmpty(item.getTitle())) {
                        return callback.onActionItemClicked(mode, item);
                    }
                    String title = item.getTitle().toString();
                    if (mCustomMenuList != null && mCustomMenuList.contains(title)) {
                        try {
                            getSelectedData(title);
                            //延迟release，防止js获取不到选中的文字
                            postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    releaseAction();
                                }
                            }, 200);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        return true;
                    } else if (mActionSelectListener != null) {
                        mActionSelectListener.onClick(title, "");
                    }
                    return callback.onActionItemClicked(mode, item);
                }

                @Override
                public void onDestroyActionMode(ActionMode mode) {
                    Log.d("chenyu", "buildCustomCallback onDestroyActionMode: start ...........");
                    callback.onDestroyActionMode(mode);
                }

                @Override
                public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
                    if (callback instanceof ActionMode.Callback2) {
                        ActionMode.Callback2 tempCallback2 = (ActionMode.Callback2) callback;
                        tempCallback2.onGetContentRect(mode, view, outRect);
                    } else {
                        super.onGetContentRect(mode, view, outRect);
                    }
                }
            };
        } else {
            customCallback = callback;
        }
        return customCallback;
    }


    /**
     * 添加自定义菜单
     *
     * @param actionMode
     */
    private ActionMode addCustomMenu(ActionMode actionMode) {
        if (actionMode != null && mCustomMenuList != null) {
            Menu menu = actionMode.getMenu();
            int groupId = 0;
            //查找"复制"选项的信息
            Log.d("chenyu", "addCustomMenu: menu size is:" + menu.size());
            for (int i = 0; i < menu.size(); i++) {
                MenuItem menuItem = menu.getItem(i);
                Log.d("chenyu", "addCustomMenu: menuItem getItem(" + i + ")" + menu.getItem(i));
                Log.d("chenyu", "addCustomMenu: menuItem getItem(" + i + ") itemId is" + menu.getItem(i).getItemId());
                if ("复制".equals(menuItem.getTitle())) {
                    groupId = menuItem.getGroupId();
                }
            }
            //添加自定义选项
            int size = mCustomMenuList.size();
            Log.d("chenyu", "size is " + size);
            for (int i = 0; i < size; i++) {
                //intent主要用于过滤菜单时使用
                Intent intent = new Intent();
                intent.setComponent(new ComponentName(getContext().getPackageName(), ""));
                String title = mCustomMenuList.get(i);
                //非系统选项，itemId只能为0，否则会崩溃（ Unable to find resource ID）
                //order可以自己选择控制，但是有些rom不行
                menu.add(groupId, 0, 0, title).setIntent(intent);
            }
            mActionMode = actionMode;
        }
        return actionMode;
    }


    /**
     * 点击的时候，获取网页中选择的文本，回掉到原生中的js接口
     *
     * @param title 传入点击的item文本，一起通过js返回给原生接口
     */
    private void getSelectedData(String title) {

        String js = "javascript:(function getSelectedText() {" + "var txt;" + "var title = \""
                + title + "\";" + "if (window.getSelection) {txt = window.getSelection().toString();"
                + "} else if (window.document.getSelection) {" + "txt = window.document.getSelection()"
                + ".toString();" + "} else if (window.document.selection) {"
                + "txt = window.document.selection.createRange().text;" + "}"
                + CUSTOM_MENU_JS_INTERFACE + ".callback(txt,title);" + "})()";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            evaluateJavascript(js, null);
        } else {
            loadUrl(js);
        }
    }


    private void releaseAction() {
        if (mActionMode != null) {
            mActionMode.finish();
            mActionMode = null;
        }
    }
}
